package ue2.esw;
/**
 * 
 */


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 
 */
public class MenuManager {

	private Map<String, MenuEntry> menuDispatchListenerMap = new TreeMap<String, MenuEntry>();
    private boolean active = true;
	private String title;
	
	public MenuManager() {
		registerMenuDispatchListener("Q", "Beenden", new MenuDispatchListener() {
			
			public void executeCommand(List<String> arguments) {
				active = false;
			}
			
			public List<String> getArgumentNames() {
				return null;
			}
		});
	}
	
	public void manageMenu() {
		while (active) {
			printMenu();
			String selection = askForInput();
			dispatchSelection(selection);
		}
	}

	private void printMenu() {
		System.out.println();
		System.out.println(getTitle());
		System.out.println(getTitle().replaceAll(".", "-"));
		System.out.println();
		for (String command : menuDispatchListenerMap.keySet()) {
			MenuEntry me = this.menuDispatchListenerMap.get(command);
			System.out.println(me.getMenuCommand() + " " + me.getMenuDescription());
		}
		System.out.print("Ihre Auswahl: ");
	}
	
	private String askForInput() {
		InputStreamReader isr = new InputStreamReader(System.in);
	    BufferedReader br = new BufferedReader(isr);
	    int retryLimit = 5;
	    int retryCount = 0;
	    while (retryLimit > retryCount) {
	    	try {
	    		String selection = br.readLine();
	    		return selection;
	    	} catch (IOException e) {
	    		retryCount++;
	    		e.printStackTrace();
	    	}
		}
	    return "Q";
	}

	private void dispatchSelection(String selection) {
		MenuEntry me = this.menuDispatchListenerMap.get(selection);
		if (me == null) {
			return;
		}
		MenuDispatchListener mdl = me.getMdl();
		List<String> argNames = mdl.getArgumentNames();
		List<String> args = null;
		if (argNames != null) {
			args = new ArrayList<String>();
			for (String currentArgument : argNames) {
				System.out.print(currentArgument + ": ");
				args.add(askForInput());
			}
		}
		mdl.executeCommand(args);
	}
	
	public void registerMenuDispatchListener(String menuCommand, String menuDescription, MenuDispatchListener mdl) {
		MenuEntry me = new MenuEntry();
		me.setMenuCommand(menuCommand);
		me.setMenuDescription(menuDescription);
		me.setMdl(mdl);
		this.menuDispatchListenerMap.put(menuCommand, me);
	}
	
	public void unregisterMenuDispatchListener(String menuCommand) {
		this.menuDispatchListenerMap.remove(menuCommand);
	}
	
	private class MenuEntry implements Serializable {
		private static final long serialVersionUID = 1L;
		private String menuCommand;
		private String menuDescription;
		private MenuDispatchListener mdl;
		public String getMenuCommand() {
			return menuCommand;
		}
		public void setMenuCommand(String menuCommand) {
			this.menuCommand = menuCommand;
		}
		public String getMenuDescription() {
			return menuDescription;
		}
		public void setMenuDescription(String menuDescription) {
			this.menuDescription = menuDescription;
		}
		public MenuDispatchListener getMdl() {
			return mdl;
		}
		public void setMdl(MenuDispatchListener mdl) {
			this.mdl = mdl;
		}
	
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

}
